package com.fingard.dsp.bank.directbank.bocom01;

import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsHisBalDetail;
import com.fingard.dsp.bank.reqrespobj.enumeration.ENDirectRight;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@Component("BOCOM01Balance")
public class BOCOM01Balance extends BOCOM01Base implements IBalance {

    // 单个余额查询和批量余额查询，统一采用流处理方式
    // 1、循环调用Req7506BalQry.readRecord()读取一个请求明细，然后写入发银行的XML对象
    // 2、发银行
    // 3、循环调用XmlTextReader.read()读取一个银行返回节点，赋值返回ATS的明细对象，
    // 然后调用RetAts7506BalQry.writeRetDetail()，写入返回ATS的明细
    public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506) throws Exception {
        // 余额查询返回ATS的对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        retAts.writeStart();// 写返回ATS的统一头部信息
        try {
            boolean hasHq = false;
            boolean hasBzj = false;
            String depositAct = getBankConfig().getValueAsString("isDepositAct");
            while (p_req7506.readRecord()) {
                //ATSES-13228虚拟户余额不允许查回
                if (p_req7506.readedDetail.higherLevelAct.length() > 0) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo("当前不支持此类型账户进行余额查询！");
                    retAts.writeEnd();
                    return retAts;
                }
                String actNum = p_req7506.readedDetail.actNum;
                if (depositAct.contains(actNum)) {
                    hasBzj = true;
                } else {
                    hasHq = true;
                }
                if (hasBzj && hasHq) {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo("暂不支持同时查询活期和保证金账户！");
                    retAts.writeEnd();
                    return retAts;
                }
            }
            p_req7506.backToTop();
            if (hasHq) {
                return d_7506_BalQry_HQ(p_req7506);
            }
            if (hasBzj) {
                return d_7506_BalQry_BZJ(p_req7506);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            e.printStackTrace();
        }
        retAts.writeEnd();
        return retAts;
    }

    public RetAts7506BalQry d_7506_BalQry_BZJ(Req7506BalQry p_req7506) throws Exception {// 余额查询
        // 余额查询返回ATS的对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        retAts.writeStart();// 写返回ATS的统一头部信息
        try {
            // 赋值通用参数
            tr_code = "310103";
            atom_tr_count = String.valueOf(p_req7506.detailCount);// 获取总共有几个帐号

            XmlTextWriter xmlWriter = new XmlTextWriter();// 发银行报文的XML对象
            // 写入通用的头部节点
            writeCommonHeader(xmlWriter);
            Map<String, HashSet<String>> actNumAndDirectRight = new HashMap<String, HashSet<String>>();//记录账号是否有现金池直联权限
            while (p_req7506.readRecord()) {
                xmlWriter.writeStartElement("body");
                xmlWriter.writeElementString("acno", p_req7506.readedDetail.actNum);
                if (p_req7506.readedDetail.directRight != null && p_req7506.readedDetail.directRight.contains(ENDirectRight.CASHPOOLS.getValue())) {
                    actNumAndDirectRight.put(p_req7506.readedDetail.actNum, p_req7506.readedDetail.directRight);
                }
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();

                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/head/particular_code");
                    if (isActiveRetCode(tmpRetCode)) {
                        String serial_record = tmpBkReader.getFirstText("/ap/body/serial_record");
                        int FieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/field_num"));
                        int RecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/record_num"));

                        java.util.List<String[]> listStrings = DealMFSText(serial_record, '|', FieldNum, RecordNum);
                        if (listStrings.size() > 0) {
                            listStrings.remove(0);
                            for (String[] strings : listStrings) {
                                RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.actNum = strings[0];
                                tmpRetDetail.actCur = convertCurToATS(strings[1]);
                                tmpRetDetail.availBal = strings[5];
                                tmpRetDetail.currBal = strings[4];
                                tmpRetDetail.yesterdayBal = strings[6];

                                if (StringHelper.isNullOrEmpty(tmpRetDetail.currBal) && StringHelper.isNullOrEmpty(tmpRetDetail.availBal)) {
                                    tmpRetDetail.respCode = "-1";
                                    if (strings.length >= 10) {
                                        tmpRetDetail.respInfo = strings[10];
                                    }
                                }
                                if (actNumAndDirectRight.size() > 0 && actNumAndDirectRight.containsKey(strings[1])) {
                                    WriteBankLogLn("调用310103 蕴通现金池信息查询接口，查询[" +strings[1] + "]现金余额...");
                                    Map<String, String> resultMap = new HashMap<String, String>();
                                    resultMap = cashpoolBal(strings[1]);
                                    if ("0".equals(resultMap.get("result"))) {
                                        tmpRetDetail.cashPoolBal = resultMap.get("cashpoolBal");
                                    } else {
                                        WriteBankLogLn("现金池余额查询：" + resultMap.get("msg"));
                                    }
                                }
                                retAts.writeRetDetail(tmpRetDetail, p_req7506.isBatch);
                            }
                        } else {
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo("处理银行返回余额内容出现异常无返回内容");
                        }

                    } else {
                        retAts.writeRespCode("-1");
                        if (tmpBkReader.getSimpleText("iRetMsg") != null && tmpBkReader.getSimpleText("iRetMsg").length() > 0) {
                            retAts.writeRespInfo(tmpBkReader.getSimpleText("iRetMsg"));
                        } else {
                            retAts.writeRespInfo(tmpBkReader.getSimpleText("RetMsg"));
                        }
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpSbMsg.toString());
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpStrRet[1]);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            e.printStackTrace();
        }
        retAts.writeEnd();
        return retAts;
    }


    public RetAts7506BalQry d_7506_BalQry_HQ(Req7506BalQry p_req7506) throws Exception {// 余额查询
        // 余额查询返回ATS的对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        retAts.writeStart();// 写返回ATS的统一头部信息
        try {
            // 赋值通用参数
            tr_code = "310101";
            atom_tr_count = String.valueOf(p_req7506.detailCount);// 获取总共有几个帐号

            XmlTextWriter xmlWriter = new XmlTextWriter();// 发银行报文的XML对象
            // 写入通用的头部节点
            writeCommonHeader(xmlWriter);
            Map<String, HashSet<String>> actNumAndDirectRight = new HashMap<String, HashSet<String>>();//记录账号是否有现金池直联权限
            while (p_req7506.readRecord()) {
                xmlWriter.writeStartElement("body");
                xmlWriter.writeElementString("acno", p_req7506.readedDetail.actNum);
                if (p_req7506.readedDetail.directRight != null && p_req7506.readedDetail.directRight.contains(ENDirectRight.CASHPOOLS.getValue())) {
                    actNumAndDirectRight.put(p_req7506.readedDetail.actNum, p_req7506.readedDetail.directRight);
                }
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();

                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/head/particular_code");
                    if (isActiveRetCode(tmpRetCode)) {
                        String serial_record = tmpBkReader.getFirstText("/ap/body/serial_record");
                        int FieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/field_num"));
                        int RecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/record_num"));

                        java.util.List<String[]> listStrings = DealMFSText(serial_record, '|', FieldNum, RecordNum);
                        if (listStrings.size() > 0) {
                            listStrings.remove(0);
                            for (String[] strings : listStrings) {
                                RetAtsBalDetail tmpRetDetail = new RetAtsBalDetail();
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.actNum = strings[1];
                                tmpRetDetail.actCur = convertCurToATS(strings[2]);
                                tmpRetDetail.availBal = strings[4];
                                tmpRetDetail.currBal = strings[3];

                                if (StringHelper.isNullOrEmpty(tmpRetDetail.currBal) && StringHelper.isNullOrEmpty(tmpRetDetail.availBal)) {
                                    tmpRetDetail.respCode = "-1";
                                    if (strings.length >= 8) {
                                        tmpRetDetail.respInfo = strings[8];
                                    }
                                }

                                if (actNumAndDirectRight.size() > 0 && actNumAndDirectRight.containsKey(strings[1])) {
                                    WriteBankLogLn("调用310103 蕴通现金池信息查询接口，查询[" + strings[1] + "]现金余额...");
                                    Map<String, String> resultMap = cashpoolBal(strings[1]);
                                    if ("0".equals(resultMap.get("result"))) {
                                        tmpRetDetail.cashPoolBal = resultMap.get("cashpoolBal");
                                    } else {
                                        WriteBankLogLn("现金池余额查询：" + resultMap.get("msg"));
                                    }
                                }
                                retAts.writeRetDetail(tmpRetDetail, p_req7506.isBatch);
                            }
                        } else {
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo("处理银行返回余额内容出现异常无返回内容");
                        }

                    } else {
                        retAts.writeRespCode("-1");
                        if (tmpBkReader.getSimpleText("iRetMsg") != null && tmpBkReader.getSimpleText("iRetMsg").length() > 0) {
                            retAts.writeRespInfo(tmpBkReader.getSimpleText("iRetMsg"));
                        } else {
                            retAts.writeRespInfo(tmpBkReader.getSimpleText("RetMsg"));
                        }
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpSbMsg.toString());
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpStrRet[1]);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            e.printStackTrace();
        }
        retAts.writeEnd();
        return retAts;
    }

    //现金池余额查询 银行接口310103 蕴通现金池信息查询
    public Map<String, String> cashpoolBal(String actnum) throws Exception {
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("result", "-1");
        try {
            // 赋值通用参数
            tr_code = "310103";
            XmlTextWriter xmlWriter = new XmlTextWriter();// 发银行报文的XML对象
            // 写入通用的头部节点
            writeCommonHeader(xmlWriter);
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("acno", actnum);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), "310103", "310103");
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();

                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/head/particular_code");
                    if (isActiveRetCode(tmpRetCode)) {
                        String serial_record = tmpBkReader.getFirstText("/ap/body/serial_record");
                        int FieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/field_num"));
                        int RecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/record_num"));

                        java.util.List<String[]> listStrings = DealMFSText(serial_record, '|', FieldNum, RecordNum);
                        if (listStrings.size() > 0) {
                            listStrings.remove(0);
                            for (String[] strings : listStrings) {
                                //账号(C40)|币 种 (C3)| 状 态(C1)| 生效日期 (C8)| 虚 拟头寸(N14.2)|实 际 头 寸(N14.2)|上日虚 拟 头 寸(N14.2)|累计透 支 限 额(N14.2)|累计透 支 金 额(N14.2)|
                                // 可支付数(N14.2)|错 误 信 息(C60)|成功标志(C1)|
                                resultMap.put("result", "0");
                                String cashpoolBal = "0.00";
                                if (!StringHelper.isNullOrEmpty(strings[4])) {
                                    cashpoolBal = strings[4];
                                }
                                resultMap.put("cashpoolBal", cashpoolBal);//现金池余额
                            }
                        } else {
                            resultMap.put("msg", "处理银行返回余额内容出现异常无返回内容");
                        }
                    } else {
                        resultMap.put("msg", "处理银行返回余额内容出现异常无返回内容");
                        if (tmpBkReader.getSimpleText("iRetMsg") != null && tmpBkReader.getSimpleText("iRetMsg").length() > 0) {
                            resultMap.put("msg", tmpBkReader.getSimpleText("iRetMsg"));
                        } else {
                            resultMap.put("msg", tmpBkReader.getSimpleText("RetMsg"));
                        }
                    }
                } else {
                    resultMap.put("msg", tmpSbMsg.toString());
                }
            } else {
                resultMap.put("msg", tmpStrRet[1]);
            }
        } catch (Exception e) {
            resultMap.put("msg", e.getMessage());
        }
        return resultMap;
    }

    @Override
    public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
        RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            // 赋值通用参数
            tr_code = "310106";
            XmlTextWriter xmlWriter = new XmlTextWriter();// 发银行报文的XML对象
            // 写入通用的头部节点
            writeCommonHeader(xmlWriter);
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("accNo", p_req7505.actNum);
            xmlWriter.writeElementString("beginDate", p_req7505.dateFrom);
            xmlWriter.writeElementString("endDate", p_req7505.dateTo);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
//            String[] tmpStrRet = {"", "<ap>\n" +
//                    "<head>\n" +
//                    "    <tr_code>310106</tr_code>\n" +
//                    "    <corp_no>0000002234</corp_no>\n" +
//                    "    <req_no>20070411113153312</req_no>\n" +
//                    "    <serial_no></serial_no>\n" +
//                    "    <next_no></next_no>\n" +
//                    "    <tr_acdt>20070511</tr_acdt>\n" +
//                    "    <tr_time>100945</tr_time>\n" +
//                    "    <ans_code>0</ans_code>\n" +
//                    "    <particular_code>0000</particular_code>\n" +
//                    "    <ans_info>交易成功</ans_info>\n" +
//                    "    <particular_info></particular_info>\n" +
//                    "    <atom_tr_count>1</atom_tr_count>\n" +
//                    "</head>\n" +
//                    "<body>\n" +
//                    "    <file_flag>0</file_flag>\n" +
//                    "    <serial_record>户名|账号|开户行|账户类型|币种|会计日期|余额|可用余额|测试账户|1213123|天地银行杭州支行|2|CNY|20191223|100.00|100.00|</serial_record>\n" +
//                    "    <record_num>1</record_num>\n" +
//                    "    <field_num>8</field_num>\n" +
//                    "</body>\n" +
//                    "</ap>"};
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpAnsCode = tmpBkReader.getFirstText("/ap/head/ans_code");
                    String tmpParCode = tmpBkReader.getFirstText("/ap/head/particular_code");
                    String tmpAnsInfo = tmpBkReader.getFirstText("/ap/head/ans_info");
                    String tmpParInfo = tmpBkReader.getFirstText("/ap/head/particular_info");
                    if ("0".equals(tmpAnsCode) && "0000".equals(tmpParCode)) {
                        String serial_record = tmpBkReader.getFirstText("/ap/body/serial_record");
                        int FieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/field_num"));
                        int RecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/body/record_num"));

                        if (!StringHelper.isNullOrEmpty(serial_record)) {
                            StringBuilder tmpSbLog = new StringBuilder();
                            ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(serial_record, "|", FieldNum, RecordNum + 1, tmpSbLog);
                            if (tmpSbLog.length() == 0) {
                                String cashPoolBal = "0.00";
                                if (p_req7505.directRight != null && p_req7505.directRight.contains(ENDirectRight.CASHPOOLS.getValue())) {
                                    WriteBankLogLn("调用310103 蕴通现金池信息查询接口，查询[" + p_req7505.actNum + "]现金余额...");
                                    Map<String, String> resultMap = new HashMap<String, String>();
                                    resultMap = cashpoolBal(p_req7505.actNum);
                                    if ("0".equals(resultMap.get("result"))) {
                                        cashPoolBal = resultMap.get("cashpoolBal");
                                    } else {
                                        WriteBankLogLn("现金池余额查询：" + resultMap.get("msg"));
                                    }
                                }
                                //0户名 (C60)| 1账号(C40)| 2开户行(C60) | 3账户类型(C1)| 4币种 (C3)| 5会计日期(C8)| 6余额 (N14,2)| 7可用余额(N14,2)
                                for (int i = 1; i < tmpArrayList.size(); i++) {
                                    String[] tmpEachArr = tmpArrayList.get(i);
                                    RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();
                                    tmpRetDetail.balDate = tmpEachArr[5].substring(0, 4) + "-" + tmpEachArr[5].substring(4, 6) + "-" + tmpEachArr[5].substring(6, 8);//余额日期
                                    tmpRetDetail.actBal = tmpEachArr[6];//历史余额
                                    tmpRetDetail.availBal = tmpEachArr[7];//历史可用余额
                                    tmpRetDetail.cashPoolBal = cashPoolBal;//现金池余额
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                retAts.writeRespCode("-1");
                                retAts.writeRespInfo(tmpSbLog.toString());
                            }
                        } else {
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo("处理银行返回余额内容出现异常无返回内容");
                        }
                    } else {
                        retAts.writeRespCode("-1");
                        retAts.writeRespInfo("银行返回：" + tmpAnsInfo + "," + tmpParInfo);
                    }
                } else {
                    retAts.writeRespCode("-1");
                    retAts.writeRespInfo(tmpSbMsg.toString());
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(tmpStrRet[1]);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo("历史余额查询出现异常！");
            WriteBankLogLn("历史余额查询出现异常,异常信息：" + e.getMessage());
            e.printStackTrace();
        }
        retAts.writeEnd();
        return retAts;
    }
}
